package references

import (
	"jvm/nzpJvm/instructions/base"
	"jvm/nzpJvm/runtime_area"
	"jvm/nzpJvm/runtime_area/heap"
)

// 类型转换指令
type CHECK_CAST struct{ base.Index16Instruction }

// instanceof 需要两个操作数，第一个是对运行时常量池的索引，可以定位到一个Class的符号引用
// 第二个是一个对象的引用，从操作数栈弹出
func (self *CHECK_CAST) Execute(frame *runtime_area.Frame) {

	stack:= frame.OperandStack()
	object := stack.PopRef()
	if object == nil {
		// null值可以强转为任何类型
		return
	}

	currentMethod := frame.Method()
	currentClass := currentMethod.Class()
	constantPool := currentClass.ConstantPool()
	classRef := constantPool.GetConstant(self.Index).(*heap.ClassRef)
	// 通过符号引用解析成直接引用
	class := classRef.ResolveClass()

	// 如果对象不是目标类的对象，则抛出异常，否则什么也不做，表示强转成功
	if !object.IsInstanceOf(class) {
		panic("java.lang.ClassCastException")
	}
}
